package net.pinnoocle.playservice.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.pinnoocle.playcommon.constant.Constant;
import net.pinnoocle.playcommon.exception.ShopException;
import net.pinnoocle.playcommon.response.ErrorCode;
import net.pinnoocle.playcommon.utils.BigDecimalMathUtil;
import net.pinnoocle.playcommon.utils.ConvertUtils;
import net.pinnoocle.playcommon.utils.DownloadImageLocal;
import net.pinnoocle.playcommon.utils.HelpUtils;
import net.pinnoocle.playdao.dao.MasterDao;
import net.pinnoocle.playdao.entity.*;
import net.pinnoocle.playdao.entity.page.PageModel;
import net.pinnoocle.playdao.entity.page.PageQuery;
import net.pinnoocle.playdao.entity.shopPc.master.*;
import net.pinnoocle.playdao.entity.web.QrCodeVo;
import net.pinnoocle.playdao.entity.web.group.MasterGroupListSearchParams;
import net.pinnoocle.playdao.entity.web.master.*;
import net.pinnoocle.playdao.entity.web.user.homepage.ShopInfoVo;
import net.pinnoocle.playservice.service.CommonService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 主持人(Master)表服务实现类
 *
 * @author ye
 * @since 2021-10-22 17:21:37
 */
@Service("masterService")
@Slf4j
public class MasterServiceImpl extends ServiceImpl<MasterDao, Master> {

    @Value("${upload.folder}")
    private String uploadFolder;

    @Value("${upload.mapUrl}")
    private String uploadMapUrl;

    @Autowired
    UserServiceImpl userService;
    @Autowired
    ShopServiceImpl shopService;
    @Autowired
    MasterScriptServiceImpl masterScriptService;
    @Autowired
    MasterOpenScriptServiceImpl masterOpenScriptService;
    @Autowired
    GroupServiceImpl groupService;
    @Autowired
    ScriptServiceImpl scriptService;
    @Autowired
    MasterWithdrawServiceImpl masterWithdrawService;
    @Autowired
    CommonService commonService;
    @Autowired
    ShopFinanceServiceImpl shopFinanceService;
    @Autowired
    MasterFinanceServiceImpl masterFinanceService;
    @Autowired
    ScriptLibraryServiceImpl scriptLibraryService;

    /**
     * 主持人首页
     * @return
     */
    public MasterHomePageVo homePage(){
        String userId = userService.getUserId();
        String shopId = userService.getGlobalShopId();
        Master master = this.getOne(new QueryWrapper<Master>()
                .lambda()
                .eq(Master::getUserId, userId)
                .eq(Master::getJobStatus, 0)
                .eq(Master::getIsCheck, 1));
        if(Objects.isNull(master)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"你还不是主持人，去申请吧");
        }
        if(Objects.nonNull(master.getExpireDate())){
            boolean isExpire = HelpUtils.compareDateToNow(master.getExpireDate());
            if(isExpire){
                throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"你的主持人身份已过期，请联系门店");
            }
        }
        MasterHomePageVo masterHomePageVo = ConvertUtils.sourceToTarget(master, MasterHomePageVo.class);
        masterHomePageVo.setWorkStartDate(DateUtil.today());
        Shop shop = shopService.getById(shopId);
        ShopInfoVo shopInfoVo = ConvertUtils.sourceToTarget(shop, ShopInfoVo.class);
        masterHomePageVo.setShopInfoVo(shopInfoVo);
        return masterHomePageVo;
    }

    /**
     * 店铺端主持人列表
     * @param searchParams
     * @return
     */
    public PageModel<MasterListPageVo> shopMasterList(MasterListSearchParams searchParams){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(searchParams.getPage()));
        pageMap.put("pageSize",String.valueOf(searchParams.getPageSize()));

        if(searchParams.getShopId() == null){
            String shopId = shopService.getShopId();
            searchParams.setShopId(shopId);
        }
        Page<MasterListPageVo> list = this.baseMapper.shopMasterListWithPage(
                new PageQuery<Master>(pageMap).getPage(),searchParams);
        List<MasterListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 店铺端修改主持人信息
     * @param params
     * @return
     */
    public boolean shopUpdateMaster(UpdateMasterParams params){
        try {
            Master master = ConvertUtils.sourceToTarget(params, Master.class);
            return this.updateById(master);
        } catch (Exception e) {
            log.info("编辑主持人信息失败："+e.getMessage());
            return false;
        }
    }

    /**
     * 门店DM审核
     * @param searchParams
     * @return
     */
    public PageModel<CheckMasterListPageVo> shopWaitCheckMasterList(WaitCheckMasterSearchParams searchParams){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(searchParams.getPage()));
        pageMap.put("pageSize",String.valueOf(searchParams.getPageSize()));

        String shopId = userService.getGlobalShopId();
        searchParams.setShopId(shopId);
        Page<CheckMasterListPageVo> list = this.baseMapper.shopWaitCheckMasterList(
                new PageQuery<Master>(pageMap).getPage(),searchParams);
        List<CheckMasterListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 门店审核通过
     * @param masterId
     * @param check 1 通过 2 拒绝
     * @return
     */
    public boolean shopCheckPass(String masterId, Integer check){
        String randomNumber = HelpUtils.getRandomNumber();
        try {
            return this.baseMapper.shopCheckPass(masterId,check,randomNumber);
        } catch (Exception e) {
            log.info("审核DM失败："+e.getMessage());
            return false;
        }
    }

    /**
     * web端支持人列表
     * @param page
     * @param pageSize
     * @return
     */
    public PageModel<WebMasterListPageVo> webMasterList(Integer page,Integer pageSize){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(page));
        pageMap.put("pageSize",String.valueOf(pageSize));

        String globalShopId = userService.getGlobalShopId();
        Page<WebMasterListPageVo> list = this.baseMapper.webMasterList(
                new PageQuery<Master>(pageMap).getPage(),globalShopId);
        List<WebMasterListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 主持人热度top5
     * @return
     */
    public List<TopMasterListVo> topFiveMaster(){
        String shopId = userService.getGlobalShopId();
        List<Master> list = this.list(new QueryWrapper<Master>()
                .lambda()
                .eq(Master::getShopId, shopId)
                .eq(Master::getIsCheck, 1)
                .eq(Master::getJobStatus, 0)
                .eq(Master::getIsHot, 1)
                .orderByAsc(Master::getTotalDmTimes)
                .last("LIMIT " + Constant.TOP_NUM));
        return ConvertUtils.sourceToTarget(list,TopMasterListVo.class);
    }

    /**
     * 平台统计主持人排行
     * @return
     */
    public List<TopMasterListVo> topMasterPlatform(Integer offset){
        List<Master> list = this.list(new QueryWrapper<Master>()
                .lambda()
                .eq(Master::getIsCheck, 1)
                .eq(Master::getJobStatus, 0)
                .eq(Master::getIsHot, 1)
                .orderByAsc(Master::getTotalDmTimes)
                .last("LIMIT " + offset));
        return ConvertUtils.sourceToTarget(list,TopMasterListVo.class);
    }

    /**
     * 空闲主持人
     * @return
     */
    public List<WebMasterListPageVo> freeMasterList(String scriptId){
        String shopId = userService.getGlobalShopId();
        List<MasterScript> masterScriptList = masterScriptService.list(new QueryWrapper<MasterScript>().lambda()
                .eq(MasterScript::getShopId, shopId)
                .eq(MasterScript::getScriptId, scriptId)
                .eq(MasterScript::getIsDeleted, 0));
        List<String> masterIds = masterScriptList.stream().map(MasterScript::getMasterId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(masterIds)){
            return new ArrayList<>();
        }
        List<Master> list = this.list(new QueryWrapper<Master>().lambda()
                .eq(Master::getShopId, shopId)
                .in(Master::getMasterId,masterIds)
                .eq(Master::getJobStatus, 0)
                .eq(Master::getDmStatus, 0)
                .eq(Master::getIsCheck, 1)
                .eq(Master::getIsRest, 0));
        if(CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        return ConvertUtils.sourceToTarget(list,WebMasterListPageVo.class);
    }

    /**
     * 主持人详情
     * @param masterId
     * @param page
     * @param pageSize
     * @return
     */
    public WebMasterDetailVo masterDetail(String masterId,Integer page,Integer pageSize){
        Master master = this.getById(masterId);
        if(Objects.isNull(master)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"主持人不存在");
        }
        WebMasterDetailVo webMasterDetailVo = ConvertUtils.sourceToTarget(master, WebMasterDetailVo.class);
        PageModel<WebMasterScriptListPage> webMasterScriptListPagePageModel = masterScriptList(masterId, page, pageSize);
        webMasterDetailVo.setScriptListPagePageModel(webMasterScriptListPagePageModel);
        return webMasterDetailVo;
    }

    /**
     * 主持人会的本
     * @param masterId
     * @param page
     * @param pageSize
     * @return
     */
    public PageModel<WebMasterScriptListPage> masterAbleScriptList(String masterId,Integer page,Integer pageSize){
        return masterScriptList(masterId,page,pageSize);
    }

    /**
     * 主持人会的本列表---分页
     * @param masterId
     * @param page
     * @param pageSize
     * @return
     */
    public PageModel<WebMasterScriptListPage> masterScriptList(String masterId,Integer page,Integer pageSize){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(page));
        pageMap.put("pageSize",String.valueOf(pageSize));

        Page<WebMasterScriptListPage> list = this.baseMapper.masterScriptList(
                new PageQuery<MasterScript>(pageMap).getPage(),masterId);
        List<WebMasterScriptListPage> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        for (WebMasterScriptListPage item : records){
            String cateNames = scriptService.getNamesByIds(item.getScriptCateId(), 0);
            item.setScriptCateName(cateNames);
        }
        return new PageModel<>(list, records);
    }


    /**
     * 主持人更新信息
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMaster(UpdateMasterInfoParams params){
        try {
            String masterId = userService.getMasterId();
            String shopId = shopService.getShopId();
            Master master = ConvertUtils.sourceToTarget(params, Master.class);
            master.setMasterId(masterId);
            boolean result = this.updateById(master);
            if(result){
                List<String> scriptIds = params.getScriptIds();
                masterScriptService.addMasterScripts(masterId,shopId,scriptIds);
            }
            return result;
        } catch (Exception e) {
            log.info("主持人更新信息失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 主持人开本
     * @param params
     * @return
     */
    public boolean openScript(OpenScriptParams params){
        String masterId = userService.getMasterId();
        String shopId = userService.getGlobalShopId();
        try {
            MasterOpenScript masterOpenScript = ConvertUtils.sourceToTarget(params, MasterOpenScript.class);
            masterOpenScript.setScriptPeople(params.getStartNumber());
            masterOpenScript.setMasterId(masterId);
            masterOpenScript.setOpenNo(HelpUtils.getOrderNumber());
            masterOpenScript.setShopId(shopId);
            masterOpenScript.setCreatedTime(new Date());
            return masterOpenScriptService.save(masterOpenScript);
        } catch (Exception e) {
            log.info("开本失败:"+e.getMessage());
        }
        return false;
    }

    /**
     * 删除我会的本
     * @param masterScriptId
     * @return
     */
    public boolean deleteMyScript(String masterScriptId){
        try {
            return masterScriptService.removeById(masterScriptId);
        } catch (Exception e) {
            log.info("删除我会的本失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 组局管理
     * @param dateStr
     * @param groupType
     * @return
     */
    public List<MasterGroupListVo> myGroupList(String dateStr,Integer groupType){
        HashMap<String, String> startAndEndDate = HelpUtils.getDayStartAndEndTime(dateStr);
        String masterId = userService.getMasterId();
        if(StringUtils.isBlank(masterId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"登录失效，请重新登录");
        }
        String startDate = startAndEndDate.getOrDefault("startDate","");
        String endDate = startAndEndDate.getOrDefault("endDate","");
        MasterGroupListSearchParams searchParams = new MasterGroupListSearchParams();
        searchParams.setMasterId(masterId);
        searchParams.setStartDate(startDate);
        searchParams.setEndDate(endDate);
        searchParams.setGroupType(groupType);
        List<MasterGroupListVo> masterGroupListVos = groupService.masterGroupList(searchParams);
        if(CollectionUtils.isEmpty(masterGroupListVos)){
            return new ArrayList<>();
        }
        for (MasterGroupListVo item : masterGroupListVos){
            String cateNames = scriptService.getNamesByIds(item.getScriptCateId(), 0);
            item.setScriptCateName(cateNames);
        }
        return masterGroupListVos;
    }

    /**
     * 开始组局
     * @param groupId
     * @param masterId
     * @return
     */
    public boolean startGroup(String groupId,String masterId){
        Group group = groupService.getById(groupId);
        if(Objects.isNull(group)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"组局不存在");
        }
        if(StringUtils.isNotBlank(masterId) && !Objects.equals(group.getMasterId(), masterId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"你不是该组局的主持人，开始组局失败");
        }
        Script script = scriptService.getById(group.getScriptId());
        String masterIdNew = StringUtils.isNotBlank(masterId) ? masterId : group.getMasterId();
        group.setGroupType(2);
        try {
            boolean result = groupService.updateById(group);
            if(result){
                //更新主持人信息
                Master master = this.getById(masterIdNew);
                master.setDmStatus(1);
                master.setTotalDmTimes(master.getTotalDmTimes()+1);
                this.updateById(master);
                //更新剧本组局次数
                script.setGroupTimes(script.getGroupTimes()+1);
                scriptService.updateById(script);
                //如果该剧本是从剧本库拉取的，还要同步剧本库的组局数
                String libraryId = script.getLibraryId();
                if(StringUtils.isNotBlank(libraryId)){
                    ScriptLibrary scriptLibrary = scriptLibraryService.getById(libraryId);
                    scriptLibrary.setGroupTimes(scriptLibrary.getGroupTimes()+1);
                    scriptLibraryService.updateById(scriptLibrary);
                }
            }
            return result;
        } catch (Exception e) {
            log.info("开局失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 结束组局
     * @param groupId
     * @param masterId
     * @return
     */
    public boolean overGroup(String groupId,String masterId){
        Group group = groupService.getById(groupId);
        if(Objects.isNull(group)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"组局不存在");
        }
        if(StringUtils.isNotBlank(masterId) && !Objects.equals(group.getMasterId(), masterId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"你不是该组局的主持人，结束组局失败");
        }
        String masterIdNew = StringUtils.isNotBlank(masterId) ? masterId : group.getMasterId();
        group.setGroupType(3);
        try {
            boolean result = groupService.updateById(group);
            if(result){
                Master master = this.getById(masterIdNew);
                master.setDmStatus(0);
                return this.updateById(master);
            }
        } catch (Exception e) {
            log.info("结束组局失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 主持人财务管理
     * @param params
     * @return
     */
    public MasterFinanceVo masterFinance(MasterFinanceListSearchParams params){
        String masterId = userService.getMasterId();
        if(StringUtils.isBlank(masterId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"咨询师id获取失败");
        }
        params.setMasterId(masterId);
        String yearMonth = params.getYearMonth();
        HashMap<String, String> monthStartAndEndTime = HelpUtils.getMonthStartAndEndTime(yearMonth);
        String startDate = monthStartAndEndTime.getOrDefault("startDate","");
        String endDate = monthStartAndEndTime.getOrDefault("endDate","");
        MasterFinanceVo monthReport = this.baseMapper.getMonthReport(masterId, startDate, endDate);
        params.setStartTime(startDate);
        params.setEndTime(endDate);
        PageModel<MasterFinanceListPageVo> masterFinanceListPageVoPageModel = masterFinancePage(params);
        monthReport.setFinanceListPageVo(masterFinanceListPageVoPageModel);
        return monthReport;
    }

    /**
     * 财务管理分页
     * @param params
     * @return
     */
    public PageModel<MasterFinanceListPageVo> masterFinancePage(MasterFinanceListSearchParams params){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(params.getPage()));
        pageMap.put("pageSize",String.valueOf(params.getPageSize()));

        Page<MasterFinanceListPageVo> list = this.baseMapper.masterFinancePage(
                new PageQuery<MasterOpenScript>(pageMap).getPage(),params);
        List<MasterFinanceListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        for (MasterFinanceListPageVo item : records){
            long between = DateUtil.between(item.getStartTime(), item.getEndTime(), DateUnit.MINUTE);
            double scriptTime = HelpUtils.setScaleNumber((double) between / 60);
            item.setScriptTime(scriptTime);
        }
        return new PageModel<>(list, records);
    }

    /**
     * 主持人提现金额回显
     * @return
     */
    public CanWithdrawVo masterWithdrawView(){
        String masterId = userService.getMasterId();
        double leftSalary = leftSalary(masterId);
        double totalFreezeAmount = this.baseMapper.totalFreezeAmount(masterId);
        double leftAmount = BigDecimalMathUtil.sub(leftSalary, totalFreezeAmount);
        CanWithdrawVo canWithdrawVo = new CanWithdrawVo();
        canWithdrawVo.setCanTakeWithdrawAmount(leftAmount);
        canWithdrawVo.setFreezeWithdrawAmount(totalFreezeAmount);
        return canWithdrawVo;
    }

    /**
     * 收支明细
     * @param params
     * @return
     */
    public PageModel<FinanceDetailListPageVo> financeDetail(MasterFinanceListSearchParams params){
        if(StringUtils.isBlank(params.getMasterId())){
            String masterId = userService.getMasterId();
            params.setMasterId(masterId);
        }
        String yearMonth = params.getYearMonth();
        HashMap<String, String> monthStartAndEndTime = HelpUtils.getMonthStartAndEndTime(yearMonth);
        String startDate = monthStartAndEndTime.getOrDefault("startDate","");
        String endDate = monthStartAndEndTime.getOrDefault("endDate","");
        params.setStartTime(startDate);
        params.setEndTime(endDate);

        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(params.getPage()));
        pageMap.put("pageSize",String.valueOf(params.getPageSize()));

        Page<FinanceDetailListPageVo> list = this.baseMapper.financeDetail(
                new PageQuery<MasterFinance>(pageMap).getPage(),params);
        List<FinanceDetailListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * shopPc端DM收入明细
     * @param masterId
     * @param dateStr
     * @return
     */
    public MasterShopFinanceVo shopMasterFinanceVo(String masterId,String dateStr){
        MasterShopFinanceVo masterShopFinanceVo = new MasterShopFinanceVo();
        //获取指定月份的开始结束时间
        HashMap<String, String> monthStartAndEndTime = HelpUtils.getMonthStartAndEndTime(dateStr);
        String startDate = monthStartAndEndTime.getOrDefault("startDate","");
        String endDate = monthStartAndEndTime.getOrDefault("endDate","");
        //获取指定月份的总收入
        MasterFinanceVo monthReport = this.baseMapper.getMonthReport(masterId, startDate, endDate);
        masterShopFinanceVo.setTotalAmount(monthReport.getTotalInCome());
        //收入明细
        MasterFinanceListSearchParams searchParams = new MasterFinanceListSearchParams();
        searchParams.setMasterId(masterId);
        searchParams.setYearMonth(dateStr);
        PageModel<FinanceDetailListPageVo> financeDetailListPageVoPageModel = financeDetail(searchParams);
        masterShopFinanceVo.setFinances(financeDetailListPageVoPageModel);
        return masterShopFinanceVo;
    }

    /**
     * DM剩余结算工资
     * @param masterId
     * @return
     */
    public double leftSalary(String masterId){
        return this.baseMapper.leftSalary(masterId);
    }

    /**
     * 主持人申请复核
     * @param openId
     * @return
     */
    public boolean recheckOpenScript(String openId){
        String masterId = userService.getMasterId();
        MasterOpenScript openScript = masterOpenScriptService.getById(openId);
        if(Objects.isNull(openScript)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"开本信息不存在");
        }
        if(masterId != openScript.getMasterId()){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"不属于你的开本信息");
        }
        try {
            openScript.setIsCheck(0);
            openScript.setCreatedTime(new Date());
            return masterOpenScriptService.updateById(openScript);
        } catch (Exception e) {
            log.info("主持人申请复核:"+e.getMessage());
        }
        return false;
    }

    /**
     * 解雇主持人
     * @param masterId
     * @return
     */
    public boolean dismissMaster(String masterId){
        double leftSalary = leftSalary(masterId);
        if(leftSalary > 0){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"剩余未结算工资"+leftSalary+"元");
        }
        try {
            Master master = new Master();
            master.setMasterId(masterId);
            master.setJobStatus(1);
            return this.updateById(master);
        } catch (Exception e) {
            log.info("解雇主持人失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 主持人工资结清
     * @param masterId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean cleanMasterSalary(String masterId){
        String shopId = userService.getGlobalShopId();
        try {
            boolean result = this.baseMapper.cleanMasterSalary(masterId);
            if(result){
                double leftSalary = leftSalary(masterId);
                ShopFinance shopFinance = new ShopFinance();
                shopFinance.setShopId(shopId);
                shopFinance.setAmount(leftSalary);
                shopFinance.setFinanceType(0);
                shopFinance.setSourceName("DM薪资");
                shopFinance.setCreatedTime(new Date());
                shopFinanceService.save(shopFinance);
            }
            return result;
        } catch (Exception e) {
            log.info("结算失败："+e.getMessage());
        }
        return false;
    }


    /**
     * 主持人申请提现
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean masterWithdraw(SaveWithdrawParams params){
        String shopId = userService.getGlobalShopId();
        String masterId = userService.getMasterId();
        double leftSalary = leftSalary(masterId);
        double totalFreezeAmount = this.baseMapper.totalFreezeAmount(masterId);
        double leftAmount = BigDecimalMathUtil.sub(leftSalary, totalFreezeAmount);
        if(params.getAmount() > leftAmount){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"余额不足");
        }
        MasterWithdraw applyExists = masterWithdrawService.getOne(new QueryWrapper<MasterWithdraw>()
                .lambda()
                .eq(MasterWithdraw::getMasterId, masterId)
                .eq(MasterWithdraw::getShopId, shopId)
                .eq(MasterWithdraw::getCheckStatus,0));
        if(Objects.nonNull(applyExists)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"存在待审核提现记录，等门店审核再提现吧");
        }
        try {
            MasterWithdraw masterWithdraw = ConvertUtils.sourceToTarget(params, MasterWithdraw.class);
            masterWithdraw.setMasterId(masterId);
            masterWithdraw.setShopId(shopId);
            masterWithdraw.setCreatedTime(new Date());
            boolean result = masterWithdrawService.save(masterWithdraw);
            if(result){
                return findOrderPayWithdraw(masterId, shopId, params.getAmount(),
                        masterWithdraw.getWithdrawId());
            }
        } catch (Exception e) {
            log.info("主持人提现申请失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 主持人提现申请列表
     * @param params
     * @return
     */
    public PageModel<MasterWithdrawListPageVo> masterWithdrawList(MasterWithdrawSearchParams params){
        String shopId = userService.getGlobalShopId();
        String masterId = userService.getMasterId();
        params.setShopId(shopId);
        params.setMasterId(masterId);
        return masterWithdrawListDo(params);
    }

    /**
     * 门店PC主持人提现申请列表
     * @param params
     * @return
     */
    public PageModel<MasterWithdrawListPageVo> shopMasterWithdrawList(MasterWithdrawSearchParams params){
        String shopId = userService.getGlobalShopId();
        params.setShopId(shopId);
        return masterWithdrawListDo(params);
    }

    /**
     * 真正的分页
     * @param params
     * @return
     */
    public PageModel<MasterWithdrawListPageVo> masterWithdrawListDo(MasterWithdrawSearchParams params){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(params.getPage()));
        pageMap.put("pageSize",String.valueOf(params.getPageSize()));

        Page<MasterWithdrawListPageVo> list = this.baseMapper.masterWithdrawList(
                new PageQuery<MasterWithdraw>(pageMap).getPage(),params);
        List<MasterWithdrawListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 提现审核
     * @param withdrawId
     * @param isCheck
     * @param refuseReason
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean masterWithdrawListCheck(String withdrawId,Integer isCheck,String refuseReason){
        MasterWithdraw masterWithdraw = masterWithdrawService.getById(withdrawId);
        if(Objects.isNull(masterWithdraw)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"提现记录不存在");
        }
        String masterId = masterWithdraw.getMasterId();
        String shopId = masterWithdraw.getShopId();
        int checkStatus = isCheck == 1 ? 1 : 2;
        if(checkStatus == 2 && StringUtils.isBlank(refuseReason)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"请输入拒绝理由");
        }
        try {
            masterWithdraw.setCheckStatus(checkStatus);
            if(checkStatus == 2){
                masterWithdraw.setRefuseReason(refuseReason);
            }
            boolean result = masterWithdrawService.updateById(masterWithdraw);
            if(result){
                if(checkStatus == 1){
                    //增加主持人财务明细
                    BigDecimal masterBalance = masterFinanceService.getMasterBalance(masterId);
                    MasterFinance masterFinance = new MasterFinance();
                    masterFinance.setMasterId(masterId);
                    masterFinance.setShopId(shopId);
                    masterFinance.setIncomeAmount(masterWithdraw.getAmount());
                    masterFinance.setSourceName("提现");
                    masterFinance.setBalance(masterBalance.doubleValue());
                    masterFinance.setFinanceType(1);//支出
                    masterFinance.setCreatedTime(new Date());
                    masterFinanceService.save(masterFinance);
                    this.baseMapper.cleanMasterLeftAmount(withdrawId);
                }else{
                    this.baseMapper.cleanMasterFreezeAmount(withdrawId);
                }
            }
            return result;
        } catch (Exception e) {
            log.info("提现审核失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 咨询师海报
     * @param masterId
     * @return
     */
    public QrCodeVo groupPoster(String masterId){
        Master master = this.getById(masterId);
        if(Objects.isNull(master)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"咨询师不存在");
        }
        String shopId = userService.getGlobalShopId();
        Shop shop = shopService.getById(shopId);
        QrCodeVo qrCodeVo = new QrCodeVo();
        String wxUnlimitedCode = commonService.getWxUnlimitedCode(master.getMasterId(), shopId, "pages/index/DMdetail");
        qrCodeVo.setShopName(shop.getShopName());
        qrCodeVo.setLogo(shop.getLogo());
        qrCodeVo.setCodeTitle(master.getNickName());
        qrCodeVo.setQrCode(wxUnlimitedCode);
        if(StringUtils.isNotBlank(master.getHeadPortrait())){
            String imageName = master.getMasterId()+".jpg";
            String imageUrl = DownloadImageLocal.downloadPicture(master.getHeadPortrait(), imageName,uploadFolder+"qr/",uploadMapUrl);
            qrCodeVo.setImageUrl(imageUrl);
        }
        return qrCodeVo;
    }

    /**
     * 提现时拆单、凑单
     * @param masterId
     * @param shopId
     * @param withdrawAmount
     * @param withdrawId
     * @return
     */
    public boolean findOrderPayWithdraw(String masterId,String shopId,Double withdrawAmount,String withdrawId){
        List<MasterFinance> financeList = masterFinanceService.list(new QueryWrapper<MasterFinance>()
                .lambda()
                .eq(MasterFinance::getMasterId, masterId)
                .eq(MasterFinance::getShopId, shopId)
                .eq(MasterFinance::getFinanceType, 0));
        if(CollectionUtils.isEmpty(financeList)){
            return false;
        }
        for (MasterFinance finance : financeList){
            double leftAmount = finance.getLeftAmount();
            double freezeAmount = finance.getFreezeAmount();
            //剩余金额去掉冻结金额
            double leftAmountWithoutFreeze = BigDecimalMathUtil.sub(leftAmount, freezeAmount);
            if(leftAmountWithoutFreeze == withdrawAmount){ // 这条正好
                this.baseMapper.changeMasterFinanceSingle(withdrawAmount,finance.getFinanceId(),withdrawId);
            }else if(leftAmountWithoutFreeze > withdrawAmount){ //这条有多余
                this.baseMapper.changeMasterFinanceSingle(withdrawAmount,finance.getFinanceId(),withdrawId);
            }else{ //这条不够
                this.baseMapper.changeMasterFinanceSingle(leftAmountWithoutFreeze,finance.getFinanceId(),withdrawId);
                withdrawAmount = BigDecimalMathUtil.sub(withdrawAmount,leftAmountWithoutFreeze);
            }
        }
        return true;
    }
}